import { _decorator, Component, Node, Prefab, NodePool, instantiate } from 'cc';
const { ccclass, property } = _decorator;

interface IDictPool {
    [name: string]: NodePool;
}


@ccclass('PoolManager')
export class PoolManager{

    private static instance:PoolManager=null;
    static get Instance()
    {
        return this.instance?this.instance:(this.instance= new PoolManager(),this.instance);
    }

    private _dictPool: IDictPool = {};
    /**
     * 从对象池里获取一个节点
     * @param prefab 预制体
     * @param parent 父节点
     * @param name 存放对象池的名字，默认池子名称为item
     * @returns 
     */
    public getNode(prefab: Prefab, parent: Node,name:string=`item`){
        // let name = prefab.data.name;
        let node: Node = null;
        const pool = this._dictPool[name];
        if (pool) {
            if (pool.size() > 0) {
                node = pool.get();
            } else {
                node = instantiate(prefab);
            }
        } else {
            this._dictPool[name] = new NodePool();
            node = instantiate(prefab);
        }
        node.parent = parent;
        return node;
    }
    /**
     * 回收节点存放到对象池中
     * @param node 要回收的节点
     * @param name 回收的对象池名字,默认池子名称为item
     * @returns 
     */
    public putNode(node: Node,name:string=`item`):number{
        if(!node)
        return 0;
        node.parent = null;
        if (!this._dictPool[name]) {
            this._dictPool[name] = new NodePool();
        }
        this._dictPool[name].put(node);
        return 1;
    }
    /**
     * 回收父节点中所有子节点存放到对象池中
     * @param parentNode 要回收的父节点
     * @param name 回收的对象池名字,默认池子名称为item
     * @returns 
     */
    public putAllNode(parentNode: Node,name:string=`item`) :number
    {
        if(!parentNode)
        return 0;
        while (parentNode.children.length) {
            parentNode.children[0].parent = null;
            if (!this._dictPool[name]) {
                this._dictPool[name] = new NodePool();
            }
            this._dictPool[name].put(parentNode.children[0]);
        }
        return 1;
    }
}